package knapsack

const (
	RM_SUM = 0
	RM_MULTI = 1
	RM_MAX = 2
	RM_MIN = 3
)

type UtilFunction func (x int) float64

func MakeScalarUtilFunction (c float64) UtilFunction {
	return func (x int) float64 {
		return c * float64(x)
	}
}

func ZeroUtilFunc (x int) float64 {
	return 0
}

type KnapsackData struct {

	// object function: reduce method (const RM_)

	reduce_method  int 

	// input

	Dim, Num int
	limit_coef [][]int  // [dim][num]
	limit [] int // [dim]
	util [] UtilFunction // [num]

	total_size int

	// working space
	new_sel_ []int 
	new_sel [][]int  	  // [num][limit[0] + 1][limit[1] + 1][...] 

	sel_  []int
	sel	[][]int 	 // [num][limit[0] + 1][limit[1] + 1][...] 

	// output
	
	final_sel []int	 // [num]
	value_ []float64
	value	[][]float64  // [num][limit[0] + 1][limit[1] + 1][...] 
}

func (kd * KnapsackData) size2ind (size []int) int {
	dim := kd.Dim
	il := 0
	for i := 0; i < dim; i ++ {
		if (i != 0) {
			il *= kd.limit[i] + 1
		}
		il += size[i]
	}
	return il
}

func (kd * KnapsackData) GetFinalValue () float64 {
	return kd.value[kd.Num - 1][kd.total_size - 1]
}

func (kd * KnapsackData) GetFinalSelect (ii int) int {
      return kd.final_sel [ii]
}
